package net.hekka.canyoutalk.web.processor;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.NamingException;
import net.hekka.canyoutalk.data.constant.ConnectionConstant;
import net.hekka.canyoutalk.data.executor.PhoneBookSqlExecutor;
import net.hekka.canyoutalk.data.vo.PhoneBookVo;
import net.hekka.canyoutalk.data.vo.list.PhoneBookVoList;
import net.hekka.canyoutalk.share.database.DataSourceConnector;
import net.hekka.canyoutalk.share.property.RequestParameterProperties;
import net.hekka.canyoutalk.web.util.PageNavigator;
import net.hekka.canyoutalk.web.vo.PageVo;

/**
 * 전화번호부의 데이터를 관리하기 위한 프로세서 이다.
 * @author Jeffrey Ha
 */
public class PhoneBookProcessor {

    private boolean test = false;

    /**
     * 생성자
     */
    public PhoneBookProcessor() {
    }

    /**
     * 테스트 생성자
     * @param test true면 테스트 파일
     */
    public PhoneBookProcessor(boolean test) {
        this.test = test;
    }

    /**
     * PhoneBook 에 데이터를 저장한다.
     * @param requestParameterProperties request parameter정보를 가지고 있는 requestParameterProperties
     * @return 저장된 갯수
     */
    public int addPhoneBook(RequestParameterProperties requestParameterProperties) {
        int returnValue = 0;
        PhoneBookVo phoneBookVo;
        Connection dbConnection = null;

        try {
            System.out.println("[addPhoneBook] RequestParameterProperties: " + requestParameterProperties.toString());
            phoneBookVo = new PhoneBookVo();

            // get database connection
            dbConnection = getConnection();
            // start database transaction.
            dbConnection.setAutoCommit(false);

            String phoneNumber = requestParameterProperties.getProperty("phoneNumber");
            phoneBookVo.setNumber(phoneNumber);

            String name = requestParameterProperties.getProperty("name");
            phoneBookVo.setName(name);

            // PhoneNumber 입력
            PhoneBookSqlExecutor phoneBookSqlExecutor = new PhoneBookSqlExecutor();
            returnValue = phoneBookSqlExecutor.insertPhoneBook(dbConnection, phoneBookVo);

        } catch (SQLException ex) {
            Logger.getLogger(PhoneBookProcessor.class.getName()).log(Level.SEVERE, null, ex);
            returnValue = -1;
        } catch (NamingException ex) {
            Logger.getLogger(PhoneBookProcessor.class.getName()).log(Level.SEVERE, null, ex);
            returnValue = -1;
        } catch (Exception ex) {
            Logger.getLogger(PhoneBookProcessor.class.getName()).log(Level.SEVERE, null, ex);
            returnValue = -1;
        } finally {
            try {
                // database transaction end
                dbConnection.setAutoCommit(true);
            } catch (SQLException ex) {
            }
            cleanup(dbConnection);
            return returnValue;
        }
    }

    /**
     * PhoneBook 에 데이터를 수정한다.
     * @param requestParameterProperties request parameter정보를 가지고 있는 requestParameterProperties
     * @return 수정된 갯수
     */
    public int modifyPhoneBook(RequestParameterProperties requestParameterProperties) {
        int returnValue = 0;
        PhoneBookVo phoneBookVo;
        Connection dbConnection = null;

        try {
            System.out.println("[modifyPhoneBook] RequestParameterProperties: " + requestParameterProperties.toString());
            phoneBookVo = new PhoneBookVo();

            // get database connection
            dbConnection = getConnection();
            // start database transaction.
            dbConnection.setAutoCommit(false);

            String phoneNumber = requestParameterProperties.getProperty("phoneNumber");
            phoneBookVo.setNumber(phoneNumber);

            String name = requestParameterProperties.getProperty("name");
            phoneBookVo.setName(name);

            // PhoneNumber 입력
            PhoneBookSqlExecutor phoneBookSqlExecutor = new PhoneBookSqlExecutor();
            returnValue = phoneBookSqlExecutor.updatePhoneBook(dbConnection, phoneBookVo);

        } catch (SQLException ex) {
            Logger.getLogger(PhoneBookProcessor.class.getName()).log(Level.SEVERE, null, ex);
            returnValue = -1;
        } catch (NamingException ex) {
            Logger.getLogger(PhoneBookProcessor.class.getName()).log(Level.SEVERE, null, ex);
            returnValue = -1;
        } catch (Exception ex) {
            Logger.getLogger(PhoneBookProcessor.class.getName()).log(Level.SEVERE, null, ex);
            returnValue = -1;
        } finally {
            try {
                // database transaction end
                dbConnection.setAutoCommit(true);
            } catch (SQLException ex) {
            }
            cleanup(dbConnection);
            return returnValue;
        }
    }

   /**
     * PhoneBook 에 데이터를 삭제한다.
     * @param requestParameterProperties request parameter정보를 가지고 있는 requestParameterProperties
     * @return 삭제된 갯수
     */
    public int erasePhoneBook(RequestParameterProperties requestParameterProperties) {
        int returnValue = 0;
        Connection dbConnection = null;

        try {
            System.out.println("[erasePhoneBook] RequestParameterProperties: " + requestParameterProperties.toString());

            // get database connection
            dbConnection = getConnection();
            // start database transaction.
            dbConnection.setAutoCommit(false);

            String phoneNumber = requestParameterProperties.getProperty("phoneNumber");

            // PhoneNumber 입력
            PhoneBookSqlExecutor phoneBookSqlExecutor = new PhoneBookSqlExecutor();
            returnValue = phoneBookSqlExecutor.deletePhoneBook(dbConnection, phoneNumber);

        } catch (SQLException ex) {
            Logger.getLogger(PhoneBookProcessor.class.getName()).log(Level.SEVERE, null, ex);
            returnValue = -1;
        } catch (NamingException ex) {
            Logger.getLogger(PhoneBookProcessor.class.getName()).log(Level.SEVERE, null, ex);
            returnValue = -1;
        } catch (Exception ex) {
            Logger.getLogger(PhoneBookProcessor.class.getName()).log(Level.SEVERE, null, ex);
            returnValue = -1;
        } finally {
            try {
                // database transaction end
                dbConnection.setAutoCommit(true);
            } catch (SQLException ex) {
            }
            cleanup(dbConnection);
            return returnValue;
        }
    }

    /**
     * PhoneBook 전체 수를 구한다.
     * @return PhoneBook 전체 수
     */
    public int getCountOfPhoneBook() {
        Connection dbConnection = null;
        int totalCount = 0;

        try {
            dbConnection = getConnection();
            PhoneBookSqlExecutor phoneBookSqlExecutor = new PhoneBookSqlExecutor();
            totalCount = phoneBookSqlExecutor.getCountOfPhoneBook(dbConnection);

        } catch (SQLException ex) {
            Logger.getLogger(TempLogQueryProcessor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NamingException ex) {
            Logger.getLogger(TempLogQueryProcessor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(TempLogQueryProcessor.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            cleanup(dbConnection);
            return totalCount;
        }
    }

    /**
     * PhoneBookList 해당하는 정보를 가져온다.
     * @param requestParameterProperties request parameter정보를 가지고 있는 requestParameterProperties
     * @return PhoneBookList 해당하는 정보
     */
    public Hashtable getPhoneBookList(RequestParameterProperties requestParameterProperties) {
        Connection dbConnection = null;
        Hashtable hashtable = new Hashtable();

        try {
            dbConnection = getConnection();
            int page = Integer.parseInt(requestParameterProperties.getProperty("nowPage"));
            int queryCount = Integer.parseInt(requestParameterProperties.getProperty("queryCount"));
            int totalCount = Integer.parseInt(requestParameterProperties.getProperty("totalCount"));
            int startRow = (page - 1) * queryCount;
            PageNavigator pageNavigator = new PageNavigator(page, totalCount, queryCount, (totalCount / queryCount) + 1);
            PageVo pageVo = setPageVo(pageNavigator);
            PhoneBookSqlExecutor phoneBookSqlExecutor = new PhoneBookSqlExecutor();
            PhoneBookVoList phoneBookVoList = phoneBookSqlExecutor.getPhoneBookVoList(dbConnection, startRow, queryCount);
            hashtable.put("phoneBookVoList", phoneBookVoList);
            hashtable.put("pageVo", pageVo);
        } catch (SQLException ex) {
            Logger.getLogger(TempLogQueryProcessor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NamingException ex) {
            Logger.getLogger(TempLogQueryProcessor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(TempLogQueryProcessor.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            cleanup(dbConnection);
            return hashtable;
        }
    }

    private Connection getConnection() throws SQLException, NamingException, Exception {
        Connection dbConnection = null;
        if (test) {
            dbConnection = DatabaseTestConnector.getConnection();
        } else {
            dbConnection = DataSourceConnector.getConnection(ConnectionConstant.databaseType);
        }
        return dbConnection;
    }

    private void cleanup(Connection con) {
        DataSourceConnector.cleanup(con);
    }

     private PageVo setPageVo(PageNavigator _pageNavigator) {
        PageNavigator pageNavigator = _pageNavigator;
        PageVo pageVo = new PageVo();
        pageVo.setPageIsPrev(pageNavigator.isPrevPage());
        pageVo.setPageIsNext(pageNavigator.isNextPage());
        pageVo.setPageStartNumber(pageNavigator.getStartPage());
        pageVo.setPageEndNumber(pageNavigator.getEndPage());
        return pageVo;
    }

}
